﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sern.Abstracts.Common;
using Sern.Abstracts.Splitter;
using Sern.Common;
using Sern.ServiceImplementation;
using Sern.ServiceImplementation.Fakes;
using Sern.ServiceImplementation.MapReduce;
using Microsoft.Practices.Unity;

namespace Sern.Test.ServiceImplementation.MapReduce
{
    [TestClass]
    public class MapReduceClientAbstract_RegistersToUnity
    {
        internal class TestSplitter : MapReduceClientEnvelope<ISplitter<SelfHealingKey<string>, string>, SelfHealingKey<string>, string>
        {
            protected override void Handle(SelfHealingKey<string> key, string value, Action<object, object> nextCallback)
            {
                var split = value.Split(new char[] {' '});
                var position = 0;
                foreach(string s in split)
                {
                    var newKey = SelfHealingKey.CreateFrom(key, s, String.Format(@"{0}_{1}", key.Key, position));
                    nextCallback(newKey, 1);
                    position++;
                }
            }

            protected override void End()
            {                
            }
        }

        [TestInitialize]
        public void TestInit()
        {
            var clientId = Guid.NewGuid();
            var jobId = Guid.NewGuid();

            ComponentLocator.Reset();

            IClientInstance splitter = new TestSplitter();
            splitter.Initialize(new ClientInitializationArgument
                {
                    JobId = jobId,
                    ClientId = clientId,
                    HostName = "MyHostName",
                    LogLevel = LogLevel.None,
                    MapReduceHostUri = "http://my.host",
                    TrackerUri = "http://tracker"
                });

            IListenerFactory listenerFactory = new StubIListenerFactory
                {
                    CreateUriUriClientTypeObject =
                        (baseUri, endPtUri, clientType, instance) =>
                        new Listener
                            {
                                Open = () => { },
                                Close = () => { },
                                Dispose = () => { }
                            }
                };

            ComponentLocator.Unity.RegisterInstance(listenerFactory);
        }

        [TestMethod]
        public void Test_MapReduceDelegatesRegistered()
        {
            var
            mrDelegate
                 =
                ComponentLocator.Unity.Resolve
                    <Action<SelfHealingKey<string>, string, Action<object, object>>>
                ("ClientMapReduceDelegate");                

            Assert.IsNotNull((mrDelegate));

            Assert.IsNotNull(
                ComponentLocator.Unity.Resolve<Action>(
                "ClientEndDelegate"));


        }

        [TestMethod]
        public void Test_JobAndClientIdsRegistered()
        {
            var jobId =ComponentLocator.Unity.Resolve<Guid>("ClientJobId");
            var clientId = ComponentLocator.Unity.Resolve<Guid>("ClientId");

            Assert.IsTrue(jobId != Guid.Empty);
            Assert.IsTrue(clientId != Guid.Empty);
        }
    }
}
